import React,{useState,memo,useMemo,useCallback} from 'react';
import './index.less'


function PureAndMemo (props) {
  console.log('PureAndMemo-----rander')
  const [count,setCount] = useState(0)
  const [userInfo, setUserInfo] = useState({name:'tom',age:18});
  const add = () => {
    setCount(count+1)
  }
  const changePerson = () => {
    // let userData = userInfo 这种写法不会触发页面
    let userData = {...userInfo}
    if(userInfo.name == 'tom'){
      userData.name = 'lili'
      setUserInfo(userData)
    }else {
      userData.name = 'tom'
      setUserInfo(userData)
    }
  }
  // useMemo相当于vue计算属性
  /*
  * 不用useMemo时,点击加1或换人都会执行setState(),导致PureAndMemo组件先rander()
  *  重新生成一个caculateResult地址  所以虽然有memo包裹子组件，但每次都会再次渲染子组件
  *  使用useMemo 会把数据起来，只有当第二个参数内的数据发生变化，才会触发caculateResult改变，此时才会重新渲染子组件
  * */
  // const caculateResult = () => {
  //   return count;
  // }
  const caculateResult = useMemo(() => {
    return count;
  }, [count])

  // useCallback和useMemo功能差不多，useCallback是对方法的缓存
  /*
   * 不用userCallback时,点击加1或换人都会执行setState(),导致PureAndMemo组件先rander()
   *  重新生成一个changeName方法地址  所以虽然有memo包裹子组件，但每次都会再次渲染子组件
   *  使用useCallback 会把方法缓存起来，只有当第二个参数内的数据发生变化，才会触发changeName改变，此时才会重新渲染子组件
   * */
   // const changeName = () => {
   //   changePerson()
   // }
  const changeName =useCallback(()=>{
    changePerson()
  },[userInfo])

  const comptedParams = useMemo(() => {

  },[count,userInfo])

  const DCompontent = useMemo(
    () => (
      <div className="d mt10">
        <h4>这是D组件</h4>
        <div>count:{count}</div>
        <div>人员:{userInfo.name}</div>
      </div>
    ),[userInfo]
  );

  return (
    <div className="parent">
      <h4>这是parent组件</h4>
      <div>count:{count}</div>
      <div>人员:{userInfo.name}</div>
      <Child caculateResult={caculateResult} changeName={changeName}/>
      <B caculateResult={caculateResult}/>
      {
        DCompontent
      }
      <button className="btn" onClick={add}>加1</button>
      <button className="btn" onClick={changePerson}>换人</button>
    </div>
  );
}
export default PureAndMemo;


const Child = React.memo((props) =>{
  const {caculateResult,changeName} = props
  return (
    <div className="a">
      <h4>这是A组件</h4>
      <div>count:{caculateResult}</div>
      <button className="btn" onClick={changeName}>A组件按钮换人</button>
    </div>
  );
});

function B() {
  console.log('B---------------rander')
  return (
    <div className="b mt10">
      <h4>这是B组件</h4>
    </div>
  );
}

// function C(){
//   console.log('C---------------rander')
//   return (
//     <div className="c mt10">
//       <h4>这是C组件</h4>
//     </div>
//   );
// }



